package szcg.scheduled.service.impl;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Service;
import szcg.framework.library.base.PostServiceImpl;
import szcg.framework.library.entity.TaskDetailBean;
import szcg.framework.library.mapper.task.TaskMapper;
import szcg.scheduled.service.utils.JobBuildHelp;
import szcg.scheduled.service.entity.JobBean;
import szcg.scheduled.service.service.TaskHandleService;

import java.util.ArrayList;
import java.util.HashMap;


/**
 * 定时任务实现类
 */
@Service
public class TaskHandleServiceImpl extends PostServiceImpl implements TaskHandleService {

    private static final Logger logger = LoggerFactory.getLogger(TaskHandleServiceImpl.class);

    @Qualifier("MainSqlSessionFactory")
    private final SqlSessionFactory sqlSessionFactory;

    @Qualifier("SchedulerFactoryBean")
    private final SchedulerFactoryBean schedulerFactoryBean;


    public TaskHandleServiceImpl(SqlSessionFactory sqlSessionFactory, SchedulerFactoryBean schedulerFactoryBean) {
        this.sqlSessionFactory = sqlSessionFactory;
        this.schedulerFactoryBean = schedulerFactoryBean;
    }

    @Override
    public void startTaskForPersistence() {
        /*
         * 程序驱动完成->从数据库读取任务，逐一启动
         * status:0->运行中,1->未运行
         */
        try (SqlSession session = sqlSessionFactory.openSession(true)) {
            TaskMapper mapper = session.getMapper(TaskMapper.class);
            ArrayList<TaskDetailBean> taskList = mapper.queryAllTask();
            if (taskList == null || taskList.isEmpty()) {
                return;
            }
            for (TaskDetailBean taskBean : taskList) {
                //状态不是在运行中的
                String status = taskBean.status;
                if (status == null || !status.equals("0")) {
                    return;
                }
                try {
                    //逐一启动
                    String taskId = taskBean.taskId;
                    String cronExpression = taskBean.cronExpression;
                    //构建cron表达式trigger
                    JobBean jobBean = JobBuildHelp.JobMap.get(taskId);
                    TriggerKey triggerKey = jobBean.triggerKey;
                    JobDetail jobDetail = jobBean.jobDetail;
                    Trigger trigger = JobBuildHelp.generateTrigger(triggerKey, cronExpression);
                    schedulerFactoryBean.getScheduler().scheduleJob(jobDetail, trigger);
                    schedulerFactoryBean.getScheduler().start();//启动
                    logger.warn("任务号：{}从数据库启动成功", taskId);
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    @Override
    public String createTask(String taskId, String cronExpression, String description) {
        JobBean jobBean = JobBuildHelp.JobMap.get(taskId);
        if (jobBean == null) {
            return generateFail("无效的taskId");
        }
        /*
         * 持久化保存-创建任务
         * status:0->运行中,1->未运行
         */
        try (SqlSession session = sqlSessionFactory.openSession(true)) {
            TaskMapper mapper = session.getMapper(TaskMapper.class);
            HashMap<String, String> params = new HashMap<>();
            params.put("taskId", taskId);
            params.put("jobKey", jobBean.jobKey.toString());
            params.put("jobClassName", "szcg.scheduled.service.task.PushHandleCaseJob");
            params.put("cronExpression", cronExpression);
            params.put("status", "1");
            params.put("description", description);
            //先查询表中有无该任务
            ArrayList<TaskDetailBean> taskList = mapper.queryTaskFroId(params);
            if (taskList != null && !taskList.isEmpty()) {
                return generateFail("任务：" + taskId + "已在系统中，请勿重复创建");
            }
            mapper.saveTask(params);
            return generateSucceed("任务：" + taskId + "创建成功");
        }
    }

    @Override
    public synchronized String startTask(String taskId) {
        //1、查询scheduler是否有无该任务->避免重复执行
        try {
            JobBean jobBean = JobBuildHelp.JobMap.get(taskId);
            if (jobBean == null) {
                return generateFail("该任务未在系统定义");
            }
            JobKey jobKey = jobBean.jobKey;
            TriggerKey triggerKey = jobBean.triggerKey;
            JobDetail jobDetail =  schedulerFactoryBean.getScheduler().getJobDetail(jobKey);
            if (jobDetail != null) {
                return generateFail("taskId:" + taskId + "已在运行中");
            }
            try (SqlSession session = sqlSessionFactory.openSession(true)) {
                TaskMapper mapper = session.getMapper(TaskMapper.class);
                HashMap<String, String> params = new HashMap<>();
                params.put("taskId", taskId);
                //2、查询数据库有无该任务
                ArrayList<TaskDetailBean> taskList = mapper.queryTaskFroId(params);
                if (taskList == null || taskList.isEmpty()) {
                    return generateFail("任务：" + taskId + "没有创建");
                }
                //构建cron表达式trigger
                JobDetail taskDetail = jobBean.jobDetail;
                String cronExpression = taskList.get(0).cronExpression;
                Trigger trigger = JobBuildHelp.generateTrigger(triggerKey, cronExpression);
                schedulerFactoryBean.getScheduler().scheduleJob(taskDetail, trigger);
                schedulerFactoryBean.getScheduler().start();//启动
                params.put("status", "0");//启动状态
                mapper.updateTaskStatus(params); //更新数据库task状态
                return generateSucceed("任务号：" + taskId + "启动成功");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public String stopTask(String taskId) {
        try {
            JobBean jobBean = JobBuildHelp.JobMap.get(taskId);
            if (jobBean == null) {
                return generateFail("该任务未在系统定义");
            }
            JobKey jobKey = jobBean.jobKey;
            JobDetail jobDetail =  schedulerFactoryBean.getScheduler().getJobDetail(jobKey);
            if (jobDetail != null) {
                schedulerFactoryBean.getScheduler().deleteJob(jobKey); //通过JobKey暂停指定任务
            }
            //持久化操作
            try (SqlSession session = sqlSessionFactory.openSession(true)) {
                TaskMapper mapper = session.getMapper(TaskMapper.class);
                HashMap<String, String> params = new HashMap<>();
                params.put("taskId", taskId);
                //查询数据库有无该任务
                ArrayList<TaskDetailBean> taskList = mapper.queryTaskFroId(params);
                if (taskList == null || taskList.isEmpty()) {
                    return generateFail("任务：" + taskId + "没有创建");
                }
                params.put("status", "1");//暂停状态
                mapper.updateTaskStatus(params); //更新数据库task状态
                return generateSucceed("任务号：" + taskId + "暂停成功");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public String deleteTask(String taskId) {
        try {
            JobBean jobBean = JobBuildHelp.JobMap.get(taskId);
            if (jobBean == null) {
                return generateFail("该任务未在系统定义");
            }
            JobKey jobKey = jobBean.jobKey;
            JobDetail jobDetail =  schedulerFactoryBean.getScheduler().getJobDetail(jobKey);
            if (jobDetail != null) {
                schedulerFactoryBean.getScheduler().deleteJob(jobKey); //通过JobKey暂停指定任务
            }
            //持久化操作
            try (SqlSession session = sqlSessionFactory.openSession(true)) {
                TaskMapper mapper = session.getMapper(TaskMapper.class);
                HashMap<String, String> params = new HashMap<>();
                params.put("taskId", taskId);
                //查询数据库有无该任务
                ArrayList<TaskDetailBean> taskList = mapper.queryTaskFroId(params);
                if (taskList == null || taskList.isEmpty()) {
                    return generateFail("任务：" + taskId + "没有创建");
                }
                mapper.deleteTask(params); //更新数据库task状态
                return generateSucceed("任务号：" + taskId + "删除成功");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public String editTask(String taskId, String cronExpression, String description) {
        //1、查询scheduler是否有无该任务->避免重复执行
        try {
            JobBean jobBean = JobBuildHelp.JobMap.get(taskId);
            if (jobBean == null) {
                return generateFail("该任务未在系统定义");
            }
            // 判断任务有无运行
            JobKey jobKey = jobBean.jobKey;
            JobDetail jobDetail =  schedulerFactoryBean.getScheduler().getJobDetail(jobKey);
            if (jobDetail != null) {
                //构建cron表达式trigger
                TriggerKey triggerKey = jobBean.triggerKey;
                Trigger trigger = JobBuildHelp.generateTrigger(triggerKey, cronExpression);
                schedulerFactoryBean.getScheduler().rescheduleJob(trigger.getKey(), trigger);//更新
                schedulerFactoryBean.getScheduler().start();//启动
            }
            //查询数据库
            try (SqlSession session = sqlSessionFactory.openSession(true)) {
                TaskMapper mapper = session.getMapper(TaskMapper.class);
                HashMap<String, String> params = new HashMap<>();
                params.put("taskId", taskId);
                ArrayList<TaskDetailBean> taskList = mapper.queryTaskFroId(params);
                if (taskList == null || taskList.isEmpty()) {
                    return generateFail("任务：" + taskId + "没有创建");
                }
                //更新数据库task状态
                params.put("cronExpression", cronExpression);
                params.put("description", description);
                mapper.updateTaskDetail(params);
                return generateSucceed("任务号：" + taskId + "修改成功");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public String queryAllTask() {
        try (SqlSession session = sqlSessionFactory.openSession(true)) {
            TaskMapper mapper = session.getMapper(TaskMapper.class);
            ArrayList<TaskDetailBean> taskList = mapper.queryAllTask();
            return generateSucceed(taskList);
        }
    }
}
